import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
import os
import sys
import json
from directory_tree import DirectoryTree
from terminal_tab import TerminalTab
from ai_assistant import AIAssistant
from sidebar_ai_assistant import SidebarAIAssistant
from key_manager import KeyManagerWindow
from encryption_utils import EncryptionUtils

class TerminalApp:
    def __init__(self, root):
        self.root = root
        self.root.title("智能终端")
        self.root.geometry("1200x700")
        self.root.minsize(900, 600)
        
        # 设置中文字体
        self.default_font = ('SimHei', 10)
        
        # 创建主框架
        self.main_frame = ttk.Frame(root)
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 创建左侧目录树和右侧终端的分隔
        self.paned_window = ttk.PanedWindow(self.main_frame, orient=tk.HORIZONTAL)
        self.paned_window.pack(fill=tk.BOTH, expand=True)
        
        # 创建左侧框架用于目录树
        self.left_frame = ttk.Frame(self.paned_window, width=300, height=600)
        self.left_frame.pack_propagate(False)
        
        # 创建右侧框架用于标签页
        self.right_frame = ttk.Frame(self.paned_window)
        self.right_frame.pack_propagate(False)
        
        # 添加框架到分隔窗口 - 调整比例为目录树:终端 = 1:8
        self.paned_window.add(self.left_frame, weight=1)
        self.paned_window.add(self.right_frame, weight=8)
        
        # 初始化目录树
        self.current_path = os.getcwd()
        self.directory_tree = DirectoryTree(self.left_frame, self.current_path)
        self.directory_tree.app = self  # 设置app属性，用于与终端通信
        
        # 创建标签页控制框架
        self.tab_control_frame = ttk.Frame(self.right_frame)
        self.tab_control_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 创建按钮容器
        self.buttons_frame = ttk.Frame(self.tab_control_frame)
        self.buttons_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=(5, 0))
        
        # 创建新建标签页按钮
        self.new_tab_button = ttk.Button(self.buttons_frame, text="新建", command=self.add_new_tab)
        self.new_tab_button.pack(side=tk.LEFT, padx=(0, 5))
        
        # 创建删除标签页按钮
        self.delete_tab_button = ttk.Button(self.buttons_frame, text="删除", command=self.delete_current_tab)
        self.delete_tab_button.pack(side=tk.LEFT, padx=(0, 5))
        
        # 创建Windows常用命令菜单
        self.windows_menu_button = ttk.Menubutton(self.buttons_frame, text="Windows命令")
        self.windows_menu = tk.Menu(self.windows_menu_button, tearoff=0)
        self.windows_menu_button['menu'] = self.windows_menu
        self.windows_menu_button.pack(side=tk.LEFT, padx=(0, 5))
        
        # 添加Windows常用命令（包含xxx参数占位符）
        windows_commands = [
            "dir xxx", "cd xxx", "mkdir xxx", "rmdir xxx", "copy xxx xxx", 
            "move xxx xxx", "del xxx", "ipconfig xxx", "ping xxx", "tasklist xxx","cls",
        ]
        for cmd in windows_commands:
            self.windows_menu.add_command(label=cmd, command=lambda cmd=cmd: self.insert_command_to_terminal(cmd))
        
        # 创建Anaconda常用命令菜单
        self.anaconda_menu_button = ttk.Menubutton(self.buttons_frame, text="Anaconda命令")
        self.anaconda_menu = tk.Menu(self.anaconda_menu_button, tearoff=0)
        self.anaconda_menu_button['menu'] = self.anaconda_menu
        self.anaconda_menu_button.pack(side=tk.LEFT, padx=(0, 5))
        
        # 添加Anaconda常用命令
        anaconda_commands = [
            "conda create -n xxx", "conda activate xxx", "conda deactivate", "conda list", 
            "conda install xxx", "conda update xxx", "conda remove xxx", "conda info",
            "conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/",
            "conda config --set show_channel_urls yes"
        ]
        for cmd in anaconda_commands:
            self.anaconda_menu.add_command(label=cmd, command=lambda cmd=cmd: self.insert_command_to_terminal(cmd))
        
        # 创建Pip常用命令菜单
        self.pip_menu_button = ttk.Menubutton(self.buttons_frame, text="Pip命令")
        self.pip_menu = tk.Menu(self.pip_menu_button, tearoff=0)
        self.pip_menu_button['menu'] = self.pip_menu
        self.pip_menu_button.pack(side=tk.LEFT, padx=(0, 5))

        
        # 创建侧边栏AI助手按钮
        self.sidebar_ai_button = ttk.Button(self.buttons_frame, text="侧边栏AI助手", command=self.toggle_sidebar_ai)

        # 将侧边栏AI助手按钮放置在最右侧
        self.sidebar_ai_button.pack(side=tk.RIGHT, padx=(2, 0))        
        # 创建密钥管理按钮
        self.key_manager_button = ttk.Button(self.buttons_frame, text="密钥管理", command=self.open_key_manager)
        self.key_manager_button.pack(side=tk.RIGHT, padx=(0, 5))



        
        # 添加Pip常用命令
        pip_commands = [
            "pip install xxx", "pip uninstall xxx", "pip list", "pip show xxx", 
            "pip install --upgrade xxx", "pip install -r requirements.txt", "pip freeze > requirements.txt",
            "pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple",
            "pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/"
        ]
        for cmd in pip_commands:
            self.pip_menu.add_command(label=cmd, command=lambda cmd=cmd: self.insert_command_to_terminal(cmd))
        
        # 创建标签页控件
        self.tab_control = ttk.Notebook(self.tab_control_frame)
        self.tab_control.pack(fill=tk.BOTH, expand=True, padx=5, pady=(5, 5))
        
        # 存储所有终端标签页的引用
        self.terminal_tabs = []
        
        # 添加第一个终端标签页
        self.add_new_tab()
        
        # 绑定标签页关闭事件
        self.tab_control.bind("<<NotebookTabChanged>>", self.on_tab_changed)
        
        # 为标签页添加右键菜单功能
        self.tab_control.bind("<Button-3>", self.show_tab_context_menu)
        
        # 创建右键菜单
        self.tab_context_menu = tk.Menu(self.root, tearoff=0)
        self.tab_context_menu.add_command(label="删除标签页", command=self.delete_selected_tab)
        
        # 初始化生成命令的AI助手
        self.ai_assistant = AIAssistant(self.root, self)
        
        # 初始化侧边栏AI助手
        self.sidebar_ai_assistant = SidebarAIAssistant(self.right_frame, self)
        
        # 初始化密钥管理窗口引用
        self.key_manager_window = None
        
        # 初始化全局默认密钥名称变量
        self.default_key_name = self._load_default_key_name()
        
        # 检查密钥配置，如果没有密钥或没有默认密钥，则自动打开密钥管理窗口
        self.check_and_open_key_manager()
        
    def add_new_tab(self):
        # 创建新的终端标签页
        tab_frame = ttk.Frame(self.tab_control)
        terminal_tab = TerminalTab(tab_frame, self.current_path)
        
        # 将终端标签页的框架添加到父框架中
        terminal_tab.frame.pack(fill=tk.BOTH, expand=True)
        
        # 添加标签页到标签控件
        tab_id = len(self.tab_control.tabs()) + 1
        self.tab_control.add(tab_frame, text=f"终端 {tab_id}")
        self.tab_control.select(tab_frame)
        
        # 保存对终端标签页的引用
        self.terminal_tabs.append(terminal_tab)
        
        # 通知侧边栏AI助手有新标签页创建（如果已初始化）
        # 获取新标签页的索引
        new_tab_idx = len(self.terminal_tabs) - 1
        # 检查侧边栏AI助手是否已初始化
        if hasattr(self, 'sidebar_ai_assistant') and self.sidebar_ai_assistant:
            # 如果侧边栏AI助手可见，初始化新标签页的聊天历史
            if self.sidebar_ai_assistant.is_visible:
                if new_tab_idx not in self.sidebar_ai_assistant.chat_histories:
                    self.sidebar_ai_assistant.chat_histories[new_tab_idx] = []
                    # 只有当当前选中的标签页是新创建的标签页时，才显示欢迎消息
                    if self.tab_control.index(self.tab_control.select()) == new_tab_idx:
                        self.sidebar_ai_assistant.display_message("助手", "你好！我是你的侧边栏AI助手，有什么可以帮助你的吗？")
        
    def insert_command_to_terminal(self, command):
        # 获取当前活动标签页的索引
        current_tab_idx = self.tab_control.index(self.tab_control.select())
        
        if 0 <= current_tab_idx < len(self.terminal_tabs):
            # 获取当前活动的终端标签页
            current_terminal_tab = self.terminal_tabs[current_tab_idx]
            
            # 向终端插入命令但不执行
            current_terminal_tab.insert_text(command)
            
    def delete_current_tab(self):
        # 确保至少保留一个标签页
        if len(self.terminal_tabs) <= 1:
            # 创建一个简单的提示窗口
            warning_window = tk.Toplevel(self.root)
            warning_window.title("警告")
            warning_window.geometry("300x150")
            warning_window.resizable(False, False)
            
            # 居中显示警告窗口
            window_width = warning_window.winfo_reqwidth()
            window_height = warning_window.winfo_reqheight()
            position_right = int(self.root.winfo_screenwidth()/2 - window_width/2)
            position_down = int(self.root.winfo_screenheight()/2 - window_height/2)
            warning_window.geometry("+{0}+{1}".format(position_right, position_down))
            
            # 添加警告消息
            message = tk.Label(warning_window, text="至少需要保留一个终端标签页！", font=self.default_font, wraplength=250)
            message.pack(expand=True, pady=20)
            
            # 添加确认按钮
            ok_button = ttk.Button(warning_window, text="确定", command=warning_window.destroy)
            ok_button.pack(pady=10)
            
            # 设置警告窗口为模态
            warning_window.transient(self.root)
            warning_window.grab_set()
            self.root.wait_window(warning_window)
            
            return
        
        try:
            # 获取当前活动标签页的索引
            current_tab_idx = self.tab_control.index(self.tab_control.select())
            
            if 0 <= current_tab_idx < len(self.terminal_tabs):
                # 获取要删除的终端标签页
                terminal_tab = self.terminal_tabs[current_tab_idx]
                
                # 停止终端进程
                terminal_tab.stop()
                
                # 从标签控件中移除标签页
                tab_frame = self.tab_control.select()
                self.tab_control.forget(tab_frame)
                
                # 从列表中移除终端标签页引用
                self.terminal_tabs.pop(current_tab_idx)
                
                # 不再重新命名剩余的标签页，保持序号不变
        except Exception as e:
            print(f"删除标签页时出错: {str(e)}")
            
    def rename_terminal_tabs(self):
        # 重新命名所有标签页，使其序号连续
        for i, tab_id in enumerate(self.tab_control.tabs()):
            self.tab_control.tab(tab_id, text=f"终端 {i+1}")
    def on_tab_changed(self, event):
        # 当标签页切换时的处理
        pass
        
    def show_tab_context_menu(self, event):
        # 获取点击位置对应的标签页索引
        if self.tab_control.tabs():
            # 计算点击位置所在的标签页
            x = self.tab_control.winfo_pointerx() - self.tab_control.winfo_rootx()
            y = self.tab_control.winfo_pointery() - self.tab_control.winfo_rooty()
            
            # 获取所有标签页的位置和大小
            tab_positions = []
            for i, tab_id in enumerate(self.tab_control.tabs()):
                # 获取标签页文本
                tab_text = self.tab_control.tab(i, "text")
                # 创建一个临时标签来测量文本宽度
                temp_label = ttk.Label(self.tab_control, text=tab_text)
                temp_label.update_idletasks()
                tab_width = temp_label.winfo_reqwidth() + 20  # 加上一些边距
                temp_label.destroy()
                
                tab_positions.append(tab_width)
            
            # 计算点击位置所在的标签页
            total_width = 0
            for i, width in enumerate(tab_positions):
                if total_width <= x < total_width + width:
                    # 选择点击的标签页
                    self.tab_control.select(i)
                    # 显示右键菜单
                    self.tab_context_menu.post(event.x_root, event.y_root)
                    break
                total_width += width
        
    def delete_selected_tab(self):
        # 删除当前选中的标签页（与delete_current_tab功能相同）
        self.delete_current_tab()
        
    def change_terminal_directory(self, path):
        # 在当前活动终端中切换到指定目录
        print(f"main_window: 收到目录切换请求，目标路径: {path}")
        try:
            # 更新应用程序的当前路径
            self.current_path = path
            
            # 获取当前活动标签页的索引
            current_tab_idx = self.tab_control.index(self.tab_control.select())
            
            if 0 <= current_tab_idx < len(self.terminal_tabs):
                # 获取当前活动的终端标签页
                current_terminal_tab = self.terminal_tabs[current_tab_idx]
                
                # 调用终端的handle_cd方法切换目录
                print(f"main_window: 调用当前终端的handle_cd方法")
                current_terminal_tab.handle_cd(path)
            else:
                print(f"main_window: 无法找到当前活动的终端标签页")
        except Exception as e:
            print(f"main_window: 切换目录时出错: {str(e)}")
    
    def open_key_manager(self, is_auto_open=False):
        # 打开密钥管理窗口
        if self.key_manager_window and self.key_manager_window.window.winfo_exists():
            # 如果密钥管理窗口已经打开，将其置于前台
            self.key_manager_window.window.lift()
            self.key_manager_window.window.focus_force()
        else:
            # 创建新的密钥管理窗口
            # 如果是自动弹出的密钥管理窗口，设置force_modal=True
            # 如果是手动打开的密钥管理窗口，设置force_modal=False
            force_modal = is_auto_open
            self.key_manager_window = KeyManagerWindow(self.root, force_modal=force_modal)
            # 将主应用程序引用传递给密钥管理窗口
            self.key_manager_window.main_app = self

    def update_ai_assistant_keys(self):
        # 更新AI助手的API密钥
        # 重新加载默认密钥名称并更新全局变量
        self.default_key_name = self._load_default_key_name()
        
        # 更新主AI助手的密钥
        if hasattr(self, 'ai_assistant') and self.ai_assistant:
            self.ai_assistant.update_api_key()
        
        # 更新侧边栏AI助手的密钥
        if hasattr(self, 'sidebar_ai_assistant') and self.sidebar_ai_assistant:
            self.sidebar_ai_assistant.update_api_key()

    def _load_default_key_name(self):
        """加载默认密钥名称"""
        try:
            if os.path.exists("selected_key.json"):
                with open("selected_key.json", "r", encoding="utf-8") as f:
                    data = json.load(f)
                    return data.get("selected_key", "")
            return ""
        except Exception:
            return ""

    def check_and_open_key_manager(self):
        # 检查密钥配置，如果没有密钥或没有默认密钥，则自动打开密钥管理窗口
        try:
            encryption_utils = EncryptionUtils()

            # 检查是否存在密钥
            if not encryption_utils.key_exists():
                # 如果没有密钥，自动打开密钥管理窗口
                self.root.after(100, lambda: self.open_key_manager(is_auto_open=True))
                return

            # 检查是否存在选中的默认密钥
            keys = encryption_utils.load_keys()
            if not keys:
                # 如果密钥为空，自动打开密钥管理窗口
                self.root.after(100, lambda: self.open_key_manager(is_auto_open=True))
                return

            # 检查是否有选中的默认密钥
            selected_key_exists = False
            if os.path.exists("selected_key.json"):
                try:
                    with open("selected_key.json", "r", encoding="utf-8") as f:
                        data = json.load(f)
                        selected_key = data.get("selected_key", "")
                        if selected_key and selected_key in keys:
                            selected_key_exists = True
                            # 更新全局默认密钥名称变量
                            self.default_key_name = selected_key
                except Exception:
                    pass

            # 如果没有选中的默认密钥，自动打开密钥管理窗口
            if not selected_key_exists:
                self.root.after(100, lambda: self.open_key_manager(is_auto_open=True))
        except Exception as e:
            print(f"检查密钥配置时出错: {e}")
            # 出错时也打开密钥管理窗口
            self.root.after(100, lambda: self.open_key_manager(is_auto_open=True))

    def toggle_sidebar_ai(self):
        # 切换侧边栏AI助手的显示和隐藏
        self.sidebar_ai_assistant.toggle_visibility()

if __name__ == "__main__":
    # 确保中文显示正常
    root = tk.Tk()
    app = TerminalApp(root)
    root.mainloop()